/*
 * Log.java	2008/07/28
 *
 * Copyright 2008 Web & Zen Multimedia, All rights reserved.
 * Use is subject to license terms.
 */
package it.wzm.lightweightlog;

import java.io.Serializable;
import java.util.Properties;

/**
 * 
 * @author Leonardo Celati
 * @version 1.0
 */
public class Log extends LightweightlogObject implements Serializable {

	/** As required by serialization */
	private static final long serialVersionUID = 595978219476446888L;
	/** Service log  */
    private static boolean serviceLogEnabled;
    /** Queue... */
    private final Queue q;
    /** Set the name for this log... */
    private final String classname;
    
    /**
     * Build a default log
     */
    public Log(String classname, Properties p) {
    	super("classname",p);
    	this.setStatus(Status.INIT);
    	
    	this.classname=classname;
    	
    	// get queue and check status...	
    	if ((q = LogFactory.getQueue()).getStatus()!=Status.RUNNING) {
    		throw new LightweightlogInitializationException("Couldn't get a Queue");
    	}
    	// up and running...
    	this.setStatus(Status.RUNNING);
    }
       
	/**
     * Return the name of this logger
	 * @return the name
	 */
	public final String getClassname() {
		return classname;
	}

	/**
     * Is service log enabled ?
     * @return true or false
     */
    public static boolean isServiceLogEnabled() {
		return serviceLogEnabled;
	}
   
    /**
     * Get all debug level
     * @param tolog The object to be logged
     */
    public final void debug(Object o) {
        this.add(o, Severity.DEBUG);
    }

    /**
     * Get all info level
     * @param tolog The object to be logged
     */
    public final void info(Object o) {
        this.add(o, Severity.INFO);
    }

    /**
     * Get all warn level
     * @param tolog The object to be logged
     */
    public final void warn(Object o) {
        this.add(o, Severity.WARN);
    }

    /**
     * Get all error level
     * @param tolog The object to be logged
     */
    public final void error(Object o) {
        this.add(o, Severity.ERROR);
    }

    /**
     * Get all fatal level
     * @param tolog The object to be logged
     */
    public final void fatal(Object o) {
        this.add(o, Severity.FATAL);
    }
    
    /**
     * Build an Entry from the passed Object and Store it in Queue
     * @param o Object to log
     * @param severity The level of Severity
     */
    protected void add(Object o, Severity severity) {
    	
    	if (this.getStatus()==Status.DISABLED) {
    		return;
    	}
    	
        try {
        	// store entry...
        	q.push(new Entry(this.getName(),o, severity, this.getClassname(), System.currentTimeMillis())    ); 
        } catch (QueueException qe) {
        	System.out.println(qe);
        }
    }
    
    /**
     * Facility for logging everything passed, which will be written to System.err. Useful for debugging.
     * @param o The object to write to log
     */
    public void serviceLog(Object o) {
    	
        // basic check...
        if (!serviceLogEnabled) {
            return;
        }
        // building our entry
        Entry e;
        // check if we want to log instance of Exception or not...
        //if (o != null && o instanceof Exception) {
         //   e = new Entry(getName(),new Exception((Exception) o), Severity.SERVICE, System.currentTimeMillis());
        //} else {
         //   Throwable t = new Throwable();
            //e = new Entry(getName(),o, Severity.SERVICE, t.getStackTrace()[t.getStackTrace().length - 1].getClassName(), System.currentTimeMillis());
        //}
        // finally logging
        //System.err.print(e.getLine());
    }

    /**
     * Facility for logging a passed  Entry which will be written to System.err. Useful for debugging.
     * @param o The object to write to log
     */
    public static <E extends Entry> void serviceLog(E e) {
        System.err.print(e.getLine());
    }
    
    /**
     * Dump E to service log
     * @param <E> 
     * @param e Anything extending Entry
     */
	public  <E extends Entry> void add(E e) {
        // finally add to queue...
    	// we will try to store entry in Queue...
    	// if we fail we try to recover the Queue.
        try {     	
			//LogFactory.getQueue().push(e);
        	q.push(e);
		} catch (QueueException ex) {
			// let's behave differently with the Queue status	
						
		} catch (NullPointerException ex) {
			// if we get here getQueue returned null
			// we are in trouble deep...the Queue has probably crashed
			// let's ask the Log to init again...
			
		}
    }
	
	
	@Override
	public boolean equals(Object o) {
		// checking correct object type...
		if (o instanceof Log) {
			// two log objects are equal
			// if they have the same 'classname'
			if ( ((Log)o).getClassname().equals(this.getClassname()) )
				return true;
			else
				return false;			
		} else {
			return false;
		}
		
	}
		
    /**
     * Overwriting the inherited method from Object
     * @return Valid string
     */
    @Override
    public String toString() {
        return super.toString() + " {hc=" + this.hashCode() + ", classname=" + this.getClassname() +  "}" ;
    }    
    
    
    /**
     * Extending class can implements their own cleanup stuff here
     */
    public void shutdown() {    	
    }
    
 
}